 # -*- coding: utf-8 -*-
from PyQt4.QtCore import *
from PyQt4.QtGui import *
from PyKDE4.plasma import Plasma
from PyKDE4 import plasmascript 
from PyKDE4.kdecore import KConfigGroup, KUrl 
from PyKDE4.kdeui import KMessageBox
from PyKDE4.phonon import Phonon
from lastfm import LastFMConnection
from lastfmqt import LastFMConnectionQt
from PyKDE4.kio import KRun

class SessionKeyDialog(QDialog):

	def __init__(self, link):

		QDialog.__init__(self)
		self.link = link

		self.setWindowTitle('request last.fm session key')
		
		message = 'Visit <a href="' + link + '">this link</a> to permanently allow streaming music<br/> from last.fm to the plasmoid. Do <b>not</b> hit OK before you<br/>granted the plasmoid permission on the last.fm page.'
		
		buttons = QDialogButtonBox(QDialogButtonBox.Ok, Qt.Horizontal, self)
		self.connect(buttons, SIGNAL('accepted()'), self.emitOk)
		label = QLabel(self)
		label.setText(message)
		self.connect(label, SIGNAL('linkActivated(QString)'), self.openLinkInBrowser)
		layout = QVBoxLayout()
		layout.addWidget(label)
		layout.addWidget(buttons)
		self.setLayout(layout)

	def emitOk(self):

		self.hide()
		self.emit(SIGNAL('ok()'))

	def openLinkInBrowser(self, link):

		KRun.runUrl(KUrl(link), 'text/html', None)

class LastFMPlasmoid(plasmascript.Applet):
	
	currentTrack = None
	tracks = None
	mediaObject = None
	lastfm = None

	def __init__(self,parent,args=None):
		plasmascript.Applet.__init__(self,parent)

		self.mediaObject = Phonon.createPlayer(Phonon.MusicCategory)
		self.connect(self.mediaObject, SIGNAL('finished()'), self.playNextTrack)
		self.connect(self.mediaObject, SIGNAL('stateChanged(Phonon::State, Phonon::State)'), self.handleStateChange)

	def init(self):

		self.setAspectRatioMode(Plasma.IgnoreAspectRatio)
		self.setHasConfigurationInterface(True)
		self.theme = Plasma.Svg(self)
		self.theme.setImagePath("widgets/background")
		self.setBackgroundHints(Plasma.Applet.DefaultBackground)

		self.skipButton = Plasma.PushButton(self.applet)
		self.skipButton.setText('skip')
		self.skipButton.setEnabled(False)
		self.connect(self.skipButton, SIGNAL('clicked()'), self.playNextTrack)

		self.playStopButton = Plasma.PushButton(self.applet)
		self.playStopButton.setText('play')
		self.connect(self.playStopButton, SIGNAL('clicked()'), self.playStop)

		self.trackLabel = Plasma.Label(self.applet)
		self.trackLabel.setText('<artist> - <title>')
		
		layout = QGraphicsLinearLayout(Qt.Horizontal, self.applet)
		layout.addItem(self.trackLabel)
		layout.addItem(self.playStopButton)
		layout.addItem(self.skipButton)

		self.setLayout(layout)
		self.resize(300, 60)

	def createConnection(self):

		self.lastfm = LastFMConnectionQt()

	def createPlayer(self, source):
		
		self.mediaObject = Phonon.createPlayer(Phonon.MusicCategory, source)
		self.connect(self.mediaObject, SIGNAL('finished()'), self.playNextTrack)
		self.connect(self.mediaObject, SIGNAL('stateChanged(Phonon::State, Phonon::State)'), self.handleStateChange)

	def __del__(self):

		self.mediaObject.stop()
	
	def requestSession(self):

		self.connect(self.lastfm, SIGNAL('sessionSuccess(QString)'), self.handleSession)
		self.connect(self.lastfm, SIGNAL('sessionFailure(QString)'), self.handleError)
		self.lastfm.requestSession() # async

	def requestTracks(self):

		self.setBusy(True)
		self.connect(self.lastfm, SIGNAL('tracksSuccess(PyQt_PyObject)'), self.handleTracks)
		self.connect(self.lastfm, SIGNAL('tracksFailure(QString)'), self.handleError)
		self.lastfm.requestTracks() # async

	def showSessionDialog(self, link):

		self.sessionDialog = SessionKeyDialog(link)
		self.sessionDialog.show()
		self.connect(self.sessionDialog, SIGNAL('ok()'), self.requestSession)

	def handleError(self, message):

		self.setBusy(False)
		KMessageBox.error(None, message, 'last.fm error')

	def handleTracks(self, tracks):

		self.setBusy(False)
		self.tracks = tracks
		
		if self.mediaObject.state() != Phonon.PlayingState:
			self.playNextTrack()
	
	def handleSession(self, sessionKey):

		lastfmGroup = self.config().group('lastfm')
		sessionKeysGroup = lastfmGroup.group('sessionkeys')
		sessionKeysGroup.writeEntry(self.readUsername(), sessionKey)
		self.play()

	def handleStateChange(self, new, old):

		self.setBusy(False)
		
		if new == Phonon.PlayingState:

			self.playStopButton.setText('stop')
			self.skipButton.setEnabled(True)
			self.trackLabel.setText(self.currentTrack.artist+' - '+self.currentTrack.title)
		elif new == Phonon.StoppedState or new == Phonon.ErrorState:

			self.playStopButton.setText('play')
			self.skipButton.setEnabled(False)
			self.trackLabel.setText('<artist> - <title>')

	# methods to read stuff from the configuration files:

	def hasConfig(self):
		
		if  self.readUsername() == None:

			return False
		else:

			return True

	def configChanged(self):

		if self.hasConfig():

			self.setConfigurationRequired(False, '')

	def readSessionKey(self, username):

		configGroup = self.config()
		lastfmGroup = configGroup.group('lastfm')
		sessionKeysGroup = lastfmGroup.group('sessionkeys')

		sessionKey = sessionKeysGroup.readEntry(username,'')

		if sessionKey == '':
			return None
		else:
			return sessionKey

	def readUsername(self):

		configGroup = self.config()
		lastfmGroup = configGroup.group('lastfm')

		username = lastfmGroup.readEntry('username','')

		if username == '':
			return None
		else:
			return username

	def readStation(self):

		configGroup = self.config()
		lastfmGroup = configGroup.group('lastfm')

		similarartists = lastfmGroup.readEntry('similarartists','true')
		if similarartists == 'true':
			
			artist = lastfmGroup.readEntry('artist','minor threat')
			return 'lastfm://artist/'+artist+'/similarartists'
			
		topfans = lastfmGroup.readEntry('topfans','false')
		if topfans == 'true':

			artist = lastfmGroup.readEntry('artist','grails')
			return 'lastfm://artist/'+artist+'/fans'

		library = lastfmGroup.readEntry('library','false')
		if library == 'true':
			
			username = self.readUsername()
			return 'lastfm://user/'+username+'/library'

		neighbours = lastfmGroup.readEntry('neighbours','false')
		if neighbours == 'true':
			
			username = self.readUsername()
			return 'lastfm://user/'+username+'/neighbours'

		lovedtracks = lastfmGroup.readEntry('lovedtracks','false')
		if lovedtracks == 'true':
			
			username = self.readUsername()
			return 'lastfm://user/'+username+'/loved'

		recommendations = lastfmGroup.readEntry('recommendations','false')
		if recommendations == 'true':
			
			username = self.readUsername()
			return 'lastfm://user/'+username+'/recommended'

		tag = lastfmGroup.readEntry('tag','false')
		if tag == 'true':
			
			tag = lastfmGroup.readEntry('tag_tag','freak folk')
			return 'lastfm://globaltags/'+tag
		
	def play(self):

		if self.hasConfig() == False:

			self.setConfigurationRequired(True, 'Initial Configuration required.')
			return

		self.createConnection()
		self.setBusy(True)

		# last.fm specific:

		username = self.readUsername()
		sessionKey = self.readSessionKey(username)
		if sessionKey == None:

			self.connect(self.lastfm, SIGNAL('tokenSuccess(QString)'), self.showSessionDialog)
			self.connect(self.lastfm, SIGNAL('tokenFailure(QString)'), self.handleError)
			self.lastfm.requestToken() # async
		else:

			self.lastfm.sessionKey = str(sessionKey)
			self.connect(self.lastfm, SIGNAL('stationSuccess()'), self.requestTracks)
			self.connect(self.lastfm, SIGNAL('stationFailure(QString)'), self.handleError)
			self.lastfm.requestStation(str(self.readStation())) # async

	def stop(self):

		self.mediaObject.stop()

	def playStop(self):

		if self.mediaObject.state() != Phonon.PlayingState:

			self.play()
		else:

			self.stop()

	def playNextTrack(self):

		self.currentTrack = self.tracks.pop(0)

		if self.mediaObject == None:

			self.createPlayer(self.currentTrack)
		else:

			self.mediaObject.stop()
			self.mediaObject.setCurrentSource(self.currentTrack)

		self.setBusy(True)

		self.mediaObject.play()	# async

		if len(self.tracks) == 0:
		
			self.requestTracks()

def CreateApplet(parent):
	return LastFMPlasmoid(parent)